﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Chapter21.Models.AsyncDelegate
{
    using System.Threading;

    public static class Demo
    {
        public static void InvokeAll()
        {
            Action line = () =>
            {
                Console.ReadLine();
            };
            Invoke(WaitHandleClass, line, MutexClass, line, SingleInstance, line, SemaphoreClass, line);
        }
        public static void Invoke(params Action[] actions)
        {
            foreach (var action in actions)
            {
                action();
            }
        }
        public static void WaitHandleClass()
        {
            Func<int, int, int> d1 = (i, j) =>
                {
                    var sum = 0;
                    for (; i < j; i++)
                    {
                        Thread.Sleep(2);
                        sum += i;
                    }
                    return sum;
                };
            var ar = d1.BeginInvoke(1, 3000, null, null);
            while (true)
            {
                Console.Write(".");
                if (ar.AsyncWaitHandle.WaitOne(50, false))
                {
                    Console.WriteLine("现在可以获得这个结果了");
                    break;
                }
            }
            int result = d1.EndInvoke(ar);
            Console.WriteLine("结果: {0}", result);
        }
        public static void MutexClass()
        {
            bool createdNew;
            var mutex = new Mutex(false, "ProCSharpMutex", out createdNew);
            if (mutex.WaitOne())
            {
                try
                {

                }
                finally
                {
                    mutex.ReleaseMutex();
                }
            }
            else
            {

            }
        }
        public static void SingleInstance()
        {
            bool createdNew;
            var mutex = new Mutex(false, "SingletonWinAppMutex", out createdNew);
            if (!createdNew)
            {
                Console.WriteLine("你只能开始应用程序的一个实例");
                return;
            }
        }
        public static void SemaphoreClass()
        {

            int taskCount = 6;
            int semaphoreCount = 3;
            var semaphore = new SemaphoreSlim(semaphoreCount, semaphoreCount);
            var tasks = new Task[taskCount];
            Action<object> action = (t) =>
            {
                bool isCompleted = false;
                while (!isCompleted)
                {
                    if (semaphore.Wait(600))
                    {
                        try
                        {
                            Console.WriteLine("任务 {0} 锁定信号量", Task.CurrentId);
                            Thread.Sleep(2000);
                        }
                        finally
                        {
                            Console.WriteLine("任务 {0} 释放信号量", Task.CurrentId);
                            semaphore.Release();
                            isCompleted = true;
                        }
                    }
                    else
                    {
                        Console.WriteLine("任务 {0} 超时; 等待重试", Task.CurrentId);
                    }
                }
            };
            for (int i = 0; i < taskCount; i++)
            {
                tasks[i] = Task.Run(() => action(semaphore));
            }
            Task.WaitAll(tasks);
            Console.WriteLine("所有任务已完成");
        }
    }
}
